package service.synchronization;


import java.util.logging.Level;
import java.util.logging.Logger;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.configuration.IConfiguration;
import service.configuration.ISheetConfig;



public class SynchronizationStarter implements InitializingBean {
	
	ISynchronizer synchronizer;
	IConfiguration config;
	private boolean standalone = false;

	
	public static void main(String... args) {
		SynchronizationStarter app = new SynchronizationStarter();
		app.setStandalone(true);
		app.start();
	}
	
	
	public void start() {
		Logger.getLogger("").setLevel(Level.SEVERE);
		
	    ApplicationContext ac = new ClassPathXmlApplicationContext("/spring.xml");
	    AutowireCapableBeanFactory acbf = ac.getAutowireCapableBeanFactory();

	    synchronizer = acbf.getBean(ISynchronizer.class);
	    config = acbf.getBean(IConfiguration.class);
		
	    // Calcul du nom le plus long
	    final String treeAssociationName=  "Lien père/fils";
	    final String ownerAssociationName= "Lien de propriété";
	    final String linkAssociationName=  "Lien entre fiches";
	    int maxNameSize = Math.max(
	    				treeAssociationName.length(), 
	    				Math.max(linkAssociationName.length(),
	    						 ownerAssociationName.length())
	    			  );
		for(ISheetConfig sheetConfig : config.getAllSheetConfigs()) {
			if (maxNameSize < sheetConfig.getLabel().length()) {
				maxNameSize = sheetConfig.getLabel().length();
			}
		}
		maxNameSize += 3;
	    
	    
		
		System.out.println("Synchronisation REF -> ASOF démarrée.");
		System.out.println("- Synchronisation des fiches en cours...");
		long start = System.currentTimeMillis();
		
		synchronizer.synchronizeSheets();
		
		System.out.println("\n- Nombre de fiches dans ASOF avant et après la sychronisation : ");
		for(ISheetConfig sheetConfig : config.getAllSheetConfigs()) {
			String name = sheetConfig.getName();
			
			int nbSheetsBefore = synchronizer.getNbSheetsInAsofBeforeSynchro(name);
			int nbSheetsAdded = synchronizer.getNbSheetsAddedInAsof(name);
			int nbSheetsRemoved = synchronizer.getNbSheetsRemovedInAsof(name);
			int nbSheetsUpdated = synchronizer.getNbSheetsUpdatedInAsof(name);
			int nbSheetsAfter = nbSheetsBefore + nbSheetsAdded - nbSheetsRemoved;
			
			System.out.format("%" + maxNameSize + "s : %6d -> %6d  (%d ajoutée(s), %d supprimée(s), %d modifiée(s))\n",
							  sheetConfig.getLabel(),
							  nbSheetsBefore,
							  nbSheetsAfter,
							  nbSheetsAdded,
							  nbSheetsRemoved,
							  nbSheetsUpdated);
		}
		

		System.out.println("\n- Synchronisation des associations en cours...");
		synchronizer.synchronizeAssociations();
		//synchronizer.synchronizeAssociations_bouchon();
		
		System.out.println("\n- Nombre d'associations dans ASOF avant et après la sychronisation : ");
		
		int nbTreeAssosciationsBefore = synchronizer.getNbTreeAssociationsInAsofBeforeSynchro();
		int nbTreeAssosciationsAdded = synchronizer.getNbTreeAssociationsAddedInAsof();
		int nbTreeAssosciationsRemoved = synchronizer.getNbTreeAssociationsRemovedInAsof();
		int nbTreeAssosciationsAfter = nbTreeAssosciationsBefore + nbTreeAssosciationsAdded - nbTreeAssosciationsRemoved;
		
		System.out.format("%" + maxNameSize + "s : %6d -> %6d  (%d ajoutée(s), %d supprimée(s))\n",
				treeAssociationName,
				nbTreeAssosciationsBefore,
				nbTreeAssosciationsAfter,
				nbTreeAssosciationsAdded,
				nbTreeAssosciationsRemoved);
		
		int nbOwnerAssosciationsBefore = synchronizer.getNbOwnerAssociationsInAsofBeforeSynchro();
		int nbOwnerAssosciationsAdded = synchronizer.getNbOwnerAssociationsAddedInAsof();
		int nbOwnerAssosciationsRemoved = synchronizer.getNbOwnerAssociationsRemovedInAsof();
		int nbOwnerAssosciationsAfter = nbOwnerAssosciationsBefore + nbOwnerAssosciationsAdded - nbOwnerAssosciationsRemoved;
		
		System.out.format("%" + maxNameSize + "s : %6d -> %6d  (%d ajoutée(s), %d supprimée(s))\n",
				ownerAssociationName,
				nbOwnerAssosciationsBefore,
				nbOwnerAssosciationsAfter,
				nbOwnerAssosciationsAdded,
				nbOwnerAssosciationsRemoved);
		
		int nbLinkAssosciationsBefore = synchronizer.getNbLinkAssociationsRemovedInAsof();
		int nbLinkAssosciationsAdded = synchronizer.getNbLinkAssociationsAddedInAsof();
		int nbLinkAssosciationsRemoved = synchronizer.getNbLinkAssociationsRemovedInAsof();
		int nbLinkAssosciationsAfter = nbLinkAssosciationsAdded;
		
		System.out.format("%" + maxNameSize + "s : %6d -> %6d  (%d ajoutée(s), %d supprimée(s))\n",
				linkAssociationName,
				nbLinkAssosciationsBefore,
				nbLinkAssosciationsAfter,
				nbLinkAssosciationsAdded,
				nbLinkAssosciationsRemoved);
		
		
		/*
		System.out.println("\n- Ajout de délégations aléatoires en cours...\n");
		synchronizer.addRandomDelegations();
		*/
		
		if (! isStandalone()) {
			System.out.println("\n- Opérations post synchronsation\n");
			synchronizer.callSynchronisationListeners();
		}
		
		long time = System.currentTimeMillis() - start;
		System.out.println("Synchronisation REF -> ASOF terminée (" +
				"effectuée en " + time + " ms).");
		
	}


	public void afterPropertiesSet() throws Exception {

	}


	public boolean isStandalone() {
		return standalone;
	}


	public void setStandalone(boolean standalone) {
		this.standalone = standalone;
	}
}
